home *** CD-ROM | disk | FTP | other *** search
/ World of Video / World of Video.iso / gfxprograms / boards / retina / rblanker.lha / RBlankers / RCurves.c < prev    next >
C/C++ Source or Header  |  1995-02-13  |  22KB  |  783 lines

  1. /*
  2.  * RCurves
  3.  *
  4.  * A screen blanker for the Retina graphics card.
  5.  * By Michael Heinz, 29 March, 1994
  6.  *
  7.  */
  8.  
  9. #include <exec/memory.h>
  10. #include <exec/ports.h>
  11. #include <exec/execbase.h>
  12. #include <graphics/displayinfo.h>
  13. #include <intuition/intuitionbase.h>
  14. #include <intuition/gadgetclass.h>
  15. #include <libraries/commodities.h>
  16. #include <libraries/gadtools.h>
  17. #include <dos/dosextens.h>
  18. #include <dos/dostags.h>
  19. #include <utility/tagitem.h>
  20.  
  21. #include <clib/alib_protos.h>
  22. #include <clib/commodities_protos.h>
  23. #include <clib/dos_protos.h>
  24. #include <clib/exec_protos.h>
  25. #include <clib/gadtools_protos.h>
  26. #include <clib/graphics_protos.h>
  27. #include <clib/intuition_protos.h>
  28. #include <clib/macros.h>
  29. #include <clib/retina_protos.h>
  30. #include <retina/retina.h>
  31.  
  32. #include <string.h>
  33. #include <math.h>
  34. #include <stdlib.h>
  35.  
  36. #include <pragmas/commodities_pragmas.h>
  37. #include <pragmas/dos_pragmas.h>
  38. #include <pragmas/exec_pragmas.h>
  39. #include <pragmas/gadtools_pragmas.h>
  40. #include <pragmas/graphics_pragmas.h>
  41. #include <pragmas/intuition_pragmas.h>
  42. #include <pragmas/retina_pragmas.h>
  43. #include "blanker.h"
  44.  
  45. UBYTE *VersionString = "$VER: RCurves 2.0 (By Michael Heinz)";
  46.  
  47. unsigned char color_table[] =
  48. {
  49.     0, 0, 0, 0, 0, 70, 0, 0, 76, 0, 0, 82, 0, 0, 88, 0, 0, 94,
  50.     0, 0, 100, 0, 0, 106, 0, 0, 112, 0, 0, 118, 0, 0, 124, 0, 0, 130,
  51.     0, 0, 136, 0, 0, 142, 0, 0, 148, 0, 0, 154, 0, 0, 160, 0, 0, 166,
  52.     0, 0, 172, 0, 0, 178, 0, 0, 184, 0, 0, 190, 0, 0, 196, 0, 0, 202,
  53.     0, 0, 208, 0, 0, 214, 0, 0, 220, 0, 0, 226, 0, 0, 232, 0, 0, 238,
  54.     0, 0, 244, 0, 0, 250, 0, 0, 255, 4, 0, 255, 8, 0, 255, 12, 0, 255,
  55. 16, 0, 255, 20, 0, 255, 24, 0, 255, 28, 0, 255, 32, 0, 255, 36, 0, 255,
  56. 40, 0, 255, 44, 0, 255, 48, 0, 255, 52, 0, 255, 56, 0, 255, 60, 0, 255,
  57. 64, 0, 255, 68, 0, 255, 72, 0, 255, 76, 0, 255, 80, 0, 255, 84, 0, 255,
  58.     88, 0, 255, 92, 0, 255, 96, 0, 255, 100, 0, 255, 104, 0, 255, 108, 0, 255,
  59.     112, 0, 255, 116, 0, 255, 120, 0, 255, 124, 0, 255, 128, 0, 255, 132, 0, 255,
  60.     136, 0, 255, 140, 0, 255, 144, 0, 255, 148, 0, 255, 152, 0, 255, 156, 0, 255,
  61.     160, 0, 255, 164, 0, 255, 168, 0, 255, 172, 0, 255, 176, 0, 255, 180, 0, 255,
  62.     184, 0, 255, 188, 0, 255, 192, 0, 255, 196, 0, 255, 200, 0, 255, 204, 0, 255,
  63.     208, 0, 255, 212, 0, 255, 216, 0, 255, 220, 0, 255, 224, 0, 255, 228, 0, 255,
  64.     232, 0, 255, 236, 0, 255, 240, 0, 255, 244, 0, 255, 248, 0, 255, 252, 0, 255,
  65.     255, 0, 252, 255, 0, 248, 255, 0, 244, 255, 0, 240, 255, 0, 236, 255, 0, 232,
  66.     255, 0, 228, 255, 0, 224, 255, 0, 220, 255, 0, 216, 255, 0, 212, 255, 0, 208,
  67.     255, 0, 204, 255, 0, 200, 255, 0, 196, 255, 0, 192, 255, 0, 188, 255, 0, 184,
  68.     255, 0, 180, 255, 0, 176, 255, 0, 172, 255, 0, 168, 255, 0, 164, 255, 0, 160,
  69.     255, 0, 156, 255, 0, 152, 255, 0, 148, 255, 0, 144, 255, 0, 140, 255, 0, 136,
  70.     255, 0, 132, 255, 0, 128, 255, 0, 124, 255, 0, 120, 255, 0, 116, 255, 0, 112,
  71.     255, 0, 108, 255, 0, 104, 255, 0, 100, 255, 0, 96, 255, 0, 92, 255, 0, 88,
  72.     255, 0, 84, 255, 0, 80, 255, 0, 76, 255, 0, 72, 255, 0, 68, 255, 0, 64, 255, 0, 60,
  73.     255, 0, 56, 255, 0, 52, 255, 0, 48, 255, 0, 44, 255, 0, 40, 255, 0, 36, 255, 0, 32,
  74.     255, 0, 28, 255, 0, 24, 255, 0, 20, 255, 0, 16, 255, 0, 12, 255, 0, 8, 255, 0, 4,
  75.     255, 0, 0, 255, 4, 0, 255, 8, 0, 255, 12, 0, 255, 16, 0, 255, 20, 0, 255, 24, 0,
  76.     255, 28, 0, 255, 32, 0, 255, 36, 0, 255, 40, 0, 255, 44, 0, 255, 48, 0, 255, 52, 0,
  77. 255, 56, 0, 255, 60, 0, 255, 64, 0, 255, 68, 0, 255, 72, 0, 255, 76, 0,
  78.     255, 80, 0, 255, 84, 0, 255, 88, 0, 255, 92, 0, 255, 96, 0, 255, 100, 0,
  79.     255, 104, 0, 255, 108, 0, 255, 112, 0, 255, 116, 0, 255, 120, 0, 255, 124, 0,
  80.     255, 128, 0, 255, 132, 0, 255, 136, 0, 255, 140, 0, 255, 144, 0, 255, 148, 0,
  81.     255, 152, 0, 255, 156, 0, 255, 160, 0, 255, 164, 0, 255, 168, 0, 255, 172, 0, 255, 176, 0,
  82.     255, 180, 0, 255, 184, 0, 255, 188, 0, 255, 192, 0, 255, 196, 0, 255, 200, 0,
  83.     255, 204, 0, 255, 208, 0, 255, 212, 0, 255, 216, 0, 255, 220, 0, 255, 224, 0,
  84.     255, 228, 0, 255, 232, 0, 255, 236, 0, 255, 240, 0, 255, 244, 0, 255, 248, 0,
  85.     255, 252, 0, 255, 255, 0, 255, 255, 8, 255, 255, 16, 255, 255, 24, 255, 255, 32,
  86.     255, 255, 40, 255, 255, 48, 255, 255, 56, 255, 255, 64, 255, 255, 72, 255, 255, 80,
  87.     255, 255, 88, 255, 255, 96, 255, 255, 104, 255, 255, 112, 255, 255, 120, 255, 255, 128,
  88.     255, 255, 136, 255, 255, 144, 255, 255, 152, 255, 255, 160, 255, 255, 168, 255, 255, 176,
  89.     255, 255, 184, 255, 255, 192, 255, 255, 200, 255, 255, 208, 255, 255, 216, 255, 255, 224,
  90.     255, 255, 232, 255, 255, 240, 255, 255, 248, 255, 255, 255,
  91. };
  92.  
  93. /*
  94.  * A handy request structure for reporting that we've up and died.
  95.  */
  96. struct EasyStruct quitreq =
  97. {
  98.     sizeof(struct EasyStruct),
  99.     0,
  100.     "RCurves",
  101.     "RCurves has suffered an untimely demise\ndue to: %s",
  102.     "OK|OK"
  103. };
  104.  
  105. /*
  106.  * Commodity Broker
  107.  */
  108. struct NewBroker NewBroker =
  109. {NB_VERSION, "RCurves ", NULL,
  110.  "Silly Rabbit, Qix are for Qids!", NBU_NOTIFY | NBU_UNIQUE, COF_SHOW_HIDE,
  111.  0, NULL, 0};
  112.  
  113. #define MAX_SPEED     20L
  114. #define MAX_LINES     100L
  115. #define LINE_BUF      512L
  116.  
  117. #define MIN_LINES      10L
  118. #define DEF_LINES     20L
  119. #define DEF_SPEED     10L
  120.  
  121. #define DELTA_V          10L
  122.  
  123. LONG NumLines, Speed;
  124.  
  125. typedef struct {
  126.     unsigned char color;
  127.     int cur_point;
  128.     int last_point;
  129.     int max_points;
  130.     int tic, speed;
  131.     double av, bv, cv, dv;
  132.     double point_list[LINE_BUF][4];
  133. } PList;
  134.  
  135. PList plist;
  136.  
  137. /*
  138.  * Definitions for our configuration window
  139.  */
  140.  
  141. struct NewWindow NewBlankerWindow =
  142. {
  143.     80, 16, 0, 0, 0, 1,
  144.     IDCMP_CLOSEWINDOW | IDCMP_REFRESHWINDOW | IDCMP_GADGETDOWN |
  145.     IDCMP_GADGETUP | IDCMP_VANILLAKEY | SLIDERIDCMP | LISTVIEWIDCMP,
  146.     WINDOWCLOSE | WINDOWDRAG | WINDOWDEPTH | SIMPLE_REFRESH,
  147.     NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0,
  148.     WBENCHSCREEN
  149. };
  150.  
  151. struct Window *BlankerWindow;
  152.  
  153. #define GID_HIDE          1
  154. #define GID_BLANK         2
  155. #define GID_QUIT          3
  156. #define GID_TIMEOUT       4
  157. #define GID_CLIENT        5
  158. #define GID_LINES          6
  159. #define GID_SPEED         7
  160.  
  161. #define NUM_GADS         7
  162.  
  163. struct VisualInfo *BlankerVisualInfo;
  164. struct Gadget *BlankerGadgets;
  165. struct TextAttr BlankerAttr =
  166. {"topaz.font", TOPAZ_EIGHTY, FS_NORMAL, FPF_ROMFONT};
  167.  
  168. struct NewGadget NewBlankerGadgets[NUM_GADS] =
  169. {16, 101, 48, 12, "_Hide", &BlankerAttr, GID_HIDE, PLACETEXT_IN, NULL, NULL,
  170.  80, 101, 48, 12, "_Blank", &BlankerAttr, GID_BLANK, PLACETEXT_IN, NULL, NULL,
  171.  144, 101, 48, 12, "_Quit", &BlankerAttr, GID_QUIT, PLACETEXT_IN, NULL, NULL,
  172.  136, 5, 66, 12, "Timeout", &BlankerAttr, GID_TIMEOUT, PLACETEXT_LEFT, NULL, NULL,
  173.  136, 21, 66, 12, "Client Timeout", &BlankerAttr, GID_CLIENT, PLACETEXT_LEFT, NULL, NULL,
  174.  136, 53, 66, 12, "Speed    ", &BlankerAttr, GID_SPEED, PLACETEXT_LEFT, NULL, NULL,
  175.  136, 69, 66, 12, "Lines    ", &BlankerAttr, GID_LINES, PLACETEXT_LEFT, NULL, NULL,
  176. };
  177.  
  178. UBYTE BlankerGadgetKinds[NUM_GADS] =
  179. {
  180.     BUTTON_KIND, BUTTON_KIND, BUTTON_KIND, INTEGER_KIND, INTEGER_KIND, SLIDER_KIND,
  181.     SLIDER_KIND,
  182. };
  183.  
  184. struct TagItem ButtonGadgetTags[] =
  185. {GT_Underscore, (ULONG) '_', TAG_DONE, 0L};
  186.  
  187. struct TagItem TimeGadgetTags[] =
  188. {GTIN_Number, 0L, GTIN_MaxChars, 4L, TAG_DONE, 0L};
  189.  
  190. struct TagItem ClientGadgetTags[] =
  191. {GTIN_Number, 0L, GTIN_MaxChars, 2L, TAG_DONE, 0L};
  192.  
  193. struct TagItem SpeedGadgetTags[] =
  194. {GTSL_Level, 0L, GTSL_Min, 1L, GTSL_Max, MAX_SPEED, GTSL_LevelFormat, 0L,
  195.  GTSL_LevelPlace, PLACETEXT_LEFT, GTSL_MaxLevelLen, 2L, GA_RELVERIFY, TRUE,
  196.  TAG_DONE, 0L};
  197.  
  198. struct TagItem LinesGadgetTags[] =
  199. {GTSL_Level, 0L, GTSL_Min, MIN_LINES, GTSL_Max, MAX_LINES, GTSL_LevelFormat, 0L,
  200.  GTSL_LevelPlace, PLACETEXT_LEFT, GTSL_MaxLevelLen, 3L, GA_RELVERIFY, TRUE,
  201.  TAG_DONE, 0L};
  202.  
  203. struct TagItem *BlankerGadgetTagLists[NUM_GADS] =
  204. {
  205.     &ButtonGadgetTags[0],
  206.     &ButtonGadgetTags[0],
  207.     &ButtonGadgetTags[0],
  208.     &TimeGadgetTags[0],
  209.     &ClientGadgetTags[0],
  210.     &SpeedGadgetTags[0],
  211.     &LinesGadgetTags[0],
  212. };
  213.  
  214. void
  215. CloseBlankerWindow(void)
  216. {
  217.     if (BlankerWindow) {
  218.         /*
  219.          * We save the current position of the window
  220.          * so it will re-open in the same place, later.
  221.          */
  222.         NewBlankerWindow.LeftEdge = BlankerWindow->LeftEdge;
  223.         NewBlankerWindow.TopEdge = BlankerWindow->TopEdge;
  224.  
  225.         RemTool(BlankerGadgets);
  226.         RemTool(BlankerVisualInfo);
  227.         RemTool(BlankerWindow);
  228.         BlankerWindow = NULL;
  229.     }
  230. }
  231.  
  232. void
  233. OpenBlankerWindow(void)
  234. {
  235.     struct Gadget *Ptr;
  236.     UWORD Index;
  237.     static char Title[80];
  238.  
  239.     if (BlankerWindow == NULL) {
  240.         strcpy(Title, "RCurves = <");
  241.         strcat(Title, PopKey);
  242.         strcat(Title, ">");
  243.  
  244.         if (BlankerWindow = OpenWindowTags(&NewBlankerWindow, WA_Title, Title,
  245.                                    WA_AutoAdjust, TRUE, WA_InnerWidth,
  246.                                 212, WA_InnerHeight, 118, TAG_DONE)) {
  247.  
  248.             AddTool(BlankerWindow, CloseWindow, NULL, "Could not open the window.");
  249.  
  250.             if ((BlankerVisualInfo = GetVisualInfo(BlankerWindow->WScreen, TAG_DONE))
  251.                 == NULL) {
  252.                 RemTool(BlankerWindow);
  253.                 return;
  254.             }
  255.             AddTool(BlankerVisualInfo, FreeVisualInfo, 0L,
  256.                     "Couldn't get visual data.");
  257.  
  258.             BlankerGadgets = NULL;
  259.             if ((Ptr = CreateContext(&BlankerGadgets)) == NULL) {
  260.                 RemTool(BlankerVisualInfo);
  261.                 RemTool(BlankerWindow);
  262.                 return;
  263.             }
  264.             AddTool(Ptr, FreeGadgets, 0L, "Couldn't allocate the gadgets.");
  265.  
  266.             /*
  267.              * Here we re-load the gadgets with the current settings. 
  268.              */
  269.             TimeGadgetTags[0].ti_Data = (ULONG) TimeOut;
  270.             ClientGadgetTags[0].ti_Data = (ULONG) ClientTimeOut;
  271.             SpeedGadgetTags[0].ti_Data = (ULONG) Speed;
  272.             SpeedGadgetTags[3].ti_Data = (ULONG) "%2ld";
  273.             LinesGadgetTags[0].ti_Data = (ULONG) NumLines;
  274.             LinesGadgetTags[3].ti_Data = (ULONG) "%3ld";
  275.  
  276.             for (Index = 0L; Index < NUM_GADS; Index++) {
  277.                 NewBlankerGadgets[Index].ng_TopEdge += BlankerWindow->BorderTop;
  278.  
  279.                 NewBlankerGadgets[Index].ng_VisualInfo = BlankerVisualInfo;
  280.                 Ptr = CreateGadgetA((ULONG) BlankerGadgetKinds[Index], Ptr,
  281.                                     &NewBlankerGadgets[Index],
  282.                                     BlankerGadgetTagLists[Index]);
  283.                 if (Ptr == NULL) {
  284.                     CloseBlankerWindow();
  285.                     return;
  286.                 }
  287.                 NewBlankerGadgets[Index].ng_TopEdge -= BlankerWindow->BorderTop;
  288.             }
  289.  
  290.             AddGList(BlankerWindow, BlankerGadgets, 0L, -1L, NULL);
  291.             RefreshGadgets(BlankerGadgets, BlankerWindow, NULL);
  292.             GT_RefreshWindow(BlankerWindow, NULL);
  293.         }
  294.     }
  295.     ScreenToFront(BlankerWindow->WScreen);
  296.     WindowToFront(BlankerWindow);
  297.     ActivateWindow(BlankerWindow);
  298. }
  299.  
  300. /*
  301.  * Functions for Creating/Drawing/Removing the Lines
  302.  */
  303.  
  304. WORD __inline
  305. Insure1(WORD val)
  306. {
  307.     return (WORD)((val == 0) ? (WORD)1 : val);
  308. }
  309.  
  310. /*
  311.  * Create the list of points.
  312.  */
  313. void *__regargs
  314. CreateLines(struct RetinaScreen *Screen,
  315.             LONG NumLines, LONG Speed)
  316. {
  317.     int i;
  318.  
  319.     if (!Screen)
  320.         return NULL;
  321.  
  322.     for (i = 0; i < LINE_BUF; i++) {
  323.         plist.point_list[i][0] = -1;
  324.         plist.point_list[i][1] = -1;
  325.         plist.point_list[i][2] = -1;
  326.         plist.point_list[i][3] = -1;
  327.     }
  328.  
  329.     plist.color = 1;
  330.     plist.max_points = NumLines;
  331.     plist.speed = Speed;
  332.     plist.last_point = 0;
  333.     plist.cur_point = NumLines;
  334.     plist.point_list[NumLines][0] = drand48() * 4.0;
  335.     plist.point_list[NumLines][1] = drand48() * 4.0;
  336.     plist.point_list[NumLines][2] = drand48() * 4.0;
  337.     plist.point_list[NumLines][3] = drand48() * 4.0;
  338.     plist.av = drand48() + 0.01;
  339.     plist.bv = drand48() + 0.01;
  340.     plist.cv = drand48() + 0.01;
  341.     plist.dv = drand48() + 0.01;
  342.  
  343.     return (void *)&plist;
  344. }
  345.  
  346. int __inline __regargs
  347. Bound(double l, double *m, double u)
  348. {
  349.     if (*m < l) {
  350.         *m = l;
  351.         return 1;
  352.     }
  353.     if (*m >= u) {
  354.         *m = u - 1;
  355.         return 1;
  356.     }
  357.     return 0;
  358. }
  359.  
  360. void __inline
  361. Draw_Image(struct RetinaScreen *rs, double a, double b, double c, double d)
  362. {
  363.     double f, x, y, z, xinc, yinc, xmid, ymid;
  364.     int xi, yi, xp, yp;
  365.  
  366.     xp = -1;
  367.     yp = -1;
  368.  
  369.     xinc = (double)rs->rs_Width / 8.0;
  370.     yinc = (double)rs->rs_Height / 6.0;
  371.     xmid = (double)rs->rs_Width / 2.0;
  372.     ymid = (double)rs->rs_Height / 2.0;
  373.  
  374.     for (f = 0; f < PI2; f += FINC) {
  375.         z = a * sin(f * c) + b * cos(f * d);
  376.         x = z * cos(f);
  377.         y = z * sin(f);
  378.  
  379.         xi = (int)(x * xinc + xmid);
  380.         yi = (int)(y * yinc + ymid);
  381.  
  382.         if ((xi >= 0) && (xi < rs->rs_Width) && (yi >= 0) && (yi < rs->rs_Height)) {
  383.             if (xp < 0) {
  384.                 Retina_Line(rs, xi, yi, xi, yi);
  385.             } else {
  386.                 Retina_Line(rs, xi, yi, xp, yp);
  387.             }
  388.             xp = xi;
  389.             yp = yi;
  390.         } else {
  391.             xp = -1;
  392.         }
  393.     }
  394. }
  395.  
  396. /*
  397.  * move the Lines and redraw them 
  398.  */
  399. void __regargs
  400. DrawLines(void *xplist, struct RetinaScreen *rs)
  401. {
  402.     double *pl;
  403.     PList *plist = xplist;
  404.  
  405.     /*
  406.      * If we don't have a screen, don't draw on it! (duh.) 
  407.      */
  408.     if (!rs)
  409.         return;
  410.  
  411.     if (plist->tic) {
  412.         plist->tic--;
  413.         return;
  414.     }
  415.     plist->tic = Insure1(MAX_SPEED - plist->speed);
  416.  
  417.     pl = plist->point_list[plist->cur_point];
  418.  
  419.     Retina_SetAPen(rs, plist->color);
  420.     plist->color++;
  421.  
  422.     Draw_Image(rs, pl[0], pl[1], pl[2], pl[3]);
  423.  
  424.     plist->cur_point = (plist->cur_point + 1) % LINE_BUF;
  425.  
  426.     plist->point_list[plist->cur_point][0] = pl[0] + plist->av;
  427.     plist->point_list[plist->cur_point][1] = pl[1] + plist->bv;
  428.     plist->point_list[plist->cur_point][2] = pl[2] + plist->cv;
  429.     plist->point_list[plist->cur_point][3] = pl[3] + plist->dv;
  430.  
  431.     if (Bound(0.0, &plist->point_list[plist->cur_point][0], 4.0)) {
  432.         if (plist->av > 0) {
  433.             plist->av = -drand48() / 16.0 - 0.01;
  434.         } else {
  435.             plist->av = drand48() / 16.0 + 0.01;
  436.         }
  437.     }
  438.     if (Bound(0.0, &plist->point_list[plist->cur_point][1], 4.0)) {
  439.         if (plist->bv > 0) {
  440.             plist->bv = -drand48() / 16.0 - 0.01;
  441.         } else {
  442.             plist->bv = drand48() / 16.0 + 0.01;
  443.         }
  444.     }
  445.     if (Bound(0.0, &plist->point_list[plist->cur_point][2], 4.0)) {
  446.         if (plist->cv > 0) {
  447.             plist->cv = -drand48() / 16.0 - 0.01;
  448.         } else {
  449.             plist->cv = drand48() / 16.0 + 0.01;
  450.         }
  451.     }
  452.     if (Bound(0.0, &plist->point_list[plist->cur_point][3], 4.0)) {
  453.         if (plist->dv > 0) {
  454.             plist->dv = -drand48() / 16.0 - 0.01;
  455.         } else {
  456.             plist->dv = drand48() / 16.0 + 0.01;
  457.         }
  458.     }
  459.     Retina_SetAPen(rs, 0);
  460.     pl = plist->point_list[plist->last_point];
  461.     if (pl[0] >= 0.0)
  462.         Draw_Image(rs, pl[0], pl[1], pl[2], pl[3]);
  463.  
  464.     plist->last_point = (plist->last_point + 1) % LINE_BUF;
  465.  
  466. }
  467.  
  468. /*
  469.  * The Main Loop
  470.  */
  471.  
  472. void
  473. main(LONG argc, UBYTE * argv[])
  474. {
  475.     char **ToolTypes;
  476.     CxObj *Broker, *ObjectList, *Filter;
  477.     struct IntuiMessage *IntMsg;
  478.     CxMsg *BlankerCxMsg;
  479.     LONG ThisTimeOut, TimeUntilBlank, TimeUntilBlack;
  480.     struct RetinaScreen *BlankerScreen = NULL;
  481.     struct MsgPort *ClientPort = NULL;
  482.     int BlankFlag = 0;
  483.  
  484.     /*
  485.      * open our Libraries 
  486.      */
  487.     AddTool(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",
  488.                                                37L), CloseLibrary, 0L,
  489.             "Couldn't open the intuition.library.");
  490.     AddTool(IconBase = OpenLibrary("icon.library", 37L), CloseLibrary, 0L,
  491.             "Couldn't open the icon library.");
  492.     AddTool(CxBase = OpenLibrary("commodities.library", 37L), CloseLibrary, 0L,
  493.             "Couldn't open the commoidities library.");
  494.     AddTool(GadToolsBase = OpenLibrary("gadtools.library", 37L), CloseLibrary, 0L,
  495.             "Couldn't open the gadtools library.");
  496.     AddTool(RetinaBase = (struct _xy_RetinaBase *)OpenLibrary("retina.library", 7L),
  497.             CloseLibrary, 0L, "Couldn't open the Retina library.");
  498.  
  499.     /*
  500.      * get our Arguments 
  501.      */
  502.  
  503.     if (ToolTypes = ArgArrayInit(argc, argv))
  504.         AddTool(ToolTypes, ArgArrayDone, 0L, NULL);
  505.  
  506.     /*
  507.      * get some Signals 
  508.      */
  509.  
  510.     ServerProcess = SysBase->ThisTask;
  511.     if ((bsp_TimerSig = AllocSignal(-1L)) == -1)
  512.         Quit(10, "Could not allocate a signal.");
  513.     AddTool((void *)bsp_TimerSig, FreeSignal, 0L, NULL);
  514.     if ((bsp_InputSig = AllocSignal(-1L)) == -1)
  515.         Quit(10, "Could not allocate a signal.");
  516.     AddTool((void *)bsp_InputSig, FreeSignal, 0L, NULL);
  517.     if ((bsp_ClientSig = AllocSignal(-1L)) == -1)
  518.         Quit(10, "Could not allocate a signal.");
  519.     AddTool((void *)bsp_ClientSig, FreeSignal, 0L, NULL);
  520.  
  521.     /*
  522.      * initialize our Broker = install us as a Commodity 
  523.      */
  524.  
  525.     AddTool(CxPort = CreateMsgPort(), DeleteMsgPortSafely, 0L,
  526.             "Failed to create a port.");
  527.  
  528.     NewBroker.nb_Descr = &VersionString[6];
  529.     NewBroker.nb_Pri = ArgInt(ToolTypes, "CX_PRIORITY", DEF_CX_PRI);
  530.     NewBroker.nb_Port = CxPort;
  531.     AddTool(Broker = CxBroker(&NewBroker, NULL), DeleteCxObjAll, 0L,
  532.             NULL);
  533.  
  534.     /*
  535.      * get Time Out, Client Time Out and Display mode 
  536.      */
  537.  
  538.     TimeOut = ArgIntRange(ToolTypes, "TIMEOUT", 1L, DEF_TIMEOUT, MAX_TIMEOUT);
  539.     ClientTimeOut = ArgIntRange(ToolTypes, "CLIENTTIMEOUT", 1L, DEF_CLIENT_TIMEOUT,
  540.                                 MAX_CLIENT_TIMEOUT);
  541.  
  542.     /*
  543.      * get Parameters for Line Movement 
  544.      */
  545.  
  546.     NumLines = ArgIntRange(ToolTypes, "LINES", MIN_LINES, DEF_LINES, MAX_LINES);
  547.     Speed = ArgIntRange(ToolTypes, "SPEED", 1L, DEF_SPEED, MAX_SPEED);
  548.  
  549.     /*
  550.      * install our hot keys 
  551.      */
  552.  
  553.     PopKey = ArgString(ToolTypes, "CX_POPKEY", DEF_POPKEY);
  554.     BlankKey = ArgString(ToolTypes, "BLANKKEY", DEF_BLANKKEY);
  555.  
  556.     if ((Filter = HotKey(PopKey, CxPort, HOTKEY_OPEN_WINDOW)) == NULL)
  557.         Quit(10, "The CX_POPKEY tool type is invalid.");
  558.     else
  559.         AttachCxObj(Broker, Filter);
  560.     if (CxObjError(Filter))
  561.         Quit(10, "Could not link to the commodity list.");
  562.  
  563.     if ((Filter = HotKey(BlankKey, CxPort, HOTKEY_BLANK_SCREEN)) == NULL)
  564.         Quit(10, "The BLANKKEY tool type is invalid.");
  565.     else
  566.         AttachCxObj(Broker, Filter);
  567.     if (CxObjError(Filter))
  568.         Quit(10, "Could not link to the commodity list.");
  569.  
  570.     /*
  571.      * install our "InputHandler" 
  572.      */
  573.  
  574.     ObjectList = CxCustom(BlankerAction, 0L);
  575.     AttachCxObj(Broker, ObjectList);
  576.     if (CxObjError(ObjectList))
  577.         Quit(10, "Could not link to the commodity list.");
  578.  
  579.     (void)ActivateCxObj(Broker, TRUE);
  580.     AddTool(Broker, ActivateCxObj, 0L, "The broker broke.");
  581.  
  582.     /*
  583.      * open Window on startup if not forbidden 
  584.      */
  585.  
  586.     if (stricmp(ArgString(ToolTypes, "CX_POPUP", ""), "NO"))
  587.         OpenBlankerWindow();
  588.  
  589.     /*
  590.      * increase our Priority 
  591.      */
  592.  
  593.     AddTool(FindTask(NULL), SetTaskPri, (LONG) SetTaskPri(FindTask(NULL), SERVER_PRI),
  594.             "Findtask failed!");
  595.  
  596.     /*
  597.      * start the Loop 
  598.      */
  599.  
  600.     TimeUntilBlank = ThisTimeOut = 10L * TimeOut;
  601.     TimeUntilBlack = 10L * ClientTimeOut;
  602.  
  603.     FOREVER
  604.     {
  605.         ULONG Mask;
  606.  
  607.         if (BlankerWindow)
  608.             Mask = Wait(MASK(bsp_TimerSig) | MASK(bsp_InputSig) | MASK(bsp_ClientSig) |
  609.                         MASK(CxPort->mp_SigBit) |
  610.                         MASK(BlankerWindow->UserPort->mp_SigBit) |
  611.                         SIGBREAKF_CTRL_C);
  612.         else
  613.             Mask = Wait(MASK(bsp_TimerSig) | MASK(bsp_InputSig) | MASK(bsp_ClientSig) |
  614.                         MASK(CxPort->mp_SigBit) | SIGBREAKF_CTRL_C);
  615.  
  616.         /*
  617.          * process Window Events 
  618.          */
  619.  
  620.         while ((BlankerWindow != NULL) && (IntMsg =
  621.                                  GT_GetIMsg(BlankerWindow->UserPort)))
  622.             switch (IntMsg->Class) {
  623.                 struct Gadget *Clicked;
  624.                 UWORD Code;
  625.  
  626.             case IDCMP_CLOSEWINDOW:
  627.                 GT_ReplyIMsg(IntMsg);
  628.                 CloseBlankerWindow();
  629.                 break;
  630.             case IDCMP_REFRESHWINDOW:
  631.                 GT_BeginRefresh(BlankerWindow);
  632.                 GT_EndRefresh(BlankerWindow, TRUE);
  633.                 break;
  634.             case IDCMP_GADGETUP:
  635.                 Code = IntMsg->Code;
  636.                 Clicked = (struct Gadget *)IntMsg->IAddress;
  637.                 GT_ReplyIMsg(IntMsg);
  638.                 switch (Clicked->GadgetID) {
  639.                 case GID_HIDE:
  640.                     CloseBlankerWindow();
  641.                     break;
  642.                 case GID_QUIT:
  643.                     Quit(0, "Normal Termination.");
  644.                 case GID_BLANK:
  645.                     if (TimeUntilBlank)
  646.                         TimeUntilBlank = ThisTimeOut = 2L;
  647.                     break;
  648.                 case GID_TIMEOUT:
  649.                     if (GetNum(BlankerWindow, Clicked, 1L, &TimeOut, MAX_TIMEOUT))
  650.                         TimeUntilBlank = ThisTimeOut = 10L * TimeOut;
  651.                     break;
  652.                 case GID_CLIENT:
  653.                     if (GetNum(BlankerWindow, Clicked, 1L, &ClientTimeOut, MAX_CLIENT_TIMEOUT))
  654.                         TimeUntilBlack = 10L * ClientTimeOut;
  655.                     break;
  656.                 case GID_LINES:
  657.                     NumLines = Code;
  658.                     break;
  659.                 case GID_SPEED:
  660.                     Speed = Code;
  661.                     break;
  662.                 }
  663.                 break;
  664.             case IDCMP_VANILLAKEY:
  665.                 Code = IntMsg->Code;
  666.                 GT_ReplyIMsg(IntMsg);
  667.                 switch ((char)Code) {
  668.                 case 'H':
  669.                 case 'h':
  670.                     CloseBlankerWindow();
  671.                     break;
  672.                 case 'Q':
  673.                 case 'q':
  674.                     Quit(0, "Normal Termination.");
  675.                 case 'B':
  676.                 case 'b':
  677.                     if (TimeUntilBlank)
  678.                         TimeUntilBlank = ThisTimeOut = 2L;
  679.                 }
  680.                 break;
  681.             default:
  682.                 GT_ReplyIMsg(IntMsg);
  683.             }
  684.  
  685.         /*
  686.          * process Commodity Messages 
  687.          */
  688.  
  689.         while (BlankerCxMsg = (CxMsg *) GetMsg(CxPort))
  690.             HandleCxMsg(Broker, BlankerCxMsg, &TimeUntilBlank, &ThisTimeOut);
  691.  
  692.         /*
  693.          * check for <CTRL>-C 
  694.          */
  695.  
  696.         if (Mask & SIGBREAKF_CTRL_C)
  697.             Quit(0, "Normal Termination.");
  698.  
  699.         /*
  700.          * Input detected, unblank if necessary 
  701.          */
  702.  
  703.         if (Mask & MASK(bsp_InputSig)) {
  704.             if (BlankFlag) {
  705.                 if (ClientPort)
  706.                     RemTool(ClientPort);
  707.  
  708.                 if (BlankerScreen) {
  709.                     SpritesOn(BlankerScreen);
  710.                     RemTool(BlankerScreen);
  711.                 } else
  712.                     Retina_DisplayOn();
  713.                 BlankFlag = 0;
  714.                 ThisTimeOut = 10L * TimeOut;
  715.             }
  716.             TimeUntilBlank = ThisTimeOut;
  717.         }
  718.         /*
  719.          * client has confirmed that it is still alive 
  720.          */
  721.  
  722.         if (Mask & MASK(bsp_ClientSig)) {
  723.             if (BlankerScreen)
  724.                 Retina_DisplayOn();
  725.             TimeUntilBlack = 10L * ClientTimeOut;
  726.             BlankFlag = 1;
  727.         }
  728.         /*
  729.          * 1/10 sec is over 
  730.          */
  731.  
  732.         if (Mask & MASK(bsp_TimerSig))
  733.             if (TimeUntilBlank) {
  734.                 TimeUntilBlank--;
  735.                 if (TimeUntilBlank == 0L) {        /*
  736.                                                  * Time Out reached,
  737.                                                  * blank * the screen 
  738.                                                  */
  739.                     struct ClientMessage ClientMessage;
  740.  
  741.                     BlankFlag = 1;
  742.                     BlankerScreen = CreateScreen(color_table);
  743.                     if (BlankerScreen)
  744.                         AddTool(BlankerScreen, DestroyScreen, 0L, NULL);
  745.                     else
  746.                         /*
  747.                          * do this if we're completely out of video
  748.                          * memory. 
  749.                          */
  750.                         Retina_DisplayOff();
  751.  
  752.                     ClientMessage.bcm_Screen = BlankerScreen;
  753.                     ClientMessage.bcm_SigMask = 1L << bsp_ClientSig;
  754.                     ClientMessage.bcm_Lines = NumLines;
  755.                     ClientMessage.bcm_Speed = Speed;
  756.  
  757.                     if (ClientPort = CreateBlankerClient(RLinesClientProcess,
  758.                                                     &ClientMessage)) {
  759.                         TimeUntilBlack = 10L * ClientTimeOut;
  760.                         /*
  761.                          * try to start Client 
  762.                          */
  763.                         AddTool(ClientPort, DeleteBlankerClient, 0L, NULL);
  764.                     }
  765.                 }
  766.             } else {
  767.                 if ((BlankerScreen) && (RetinaBase->rb_FirstScreen != BlankerScreen)) {
  768.                     Retina_ScreenToFront(BlankerScreen);
  769.                     SpritesOff(BlankerScreen);
  770.                 }
  771.                 if (TimeUntilBlack) {
  772.                     TimeUntilBlack--;
  773.                     if (TimeUntilBlack == 0L)
  774.                         Retina_DisplayOff();    /*
  775.                                                  * Client Time Out *
  776.                                                  * reached, turn entire
  777.                                                  * * screen black 
  778.                                                  */
  779.                 }
  780.             }
  781.     }
  782. }
  783.